declare function print(arg:any, arg1?:any):string;
function himovieBenchMark() : void {
    class ObservedPropertyAbstract {
        private info_ : string;
        setInfo (param : string) {
            if (param && param != "") {
                this.info_ = param;
            }
        }
    }

    var templateString = "MockUp";
    var state : ObservedPropertyAbstract = new ObservedPropertyAbstract();
    state.setInfo(templateString);

    const permissionList: string[] = [
        'ohos.permission.MEDIA_LOCATION',
        'ohos.permission.READ_MEDIA',
        'ohos.permission.WRITE_MEDIA',
        'ohos.permission.DISTRIBUTED_DATASYNC',
        'ohos.permission.RUNNING_LOCK',
    ];
    
    function requestPermissionsFromUser (l : string []) : any {
        var res = {
            permissions : [...l],
            authResults : [0, 0, 0, 0]
        }
        return res;
    }

    function addZero(num): string {
        return num < 10 ? '0' + num : num;
    }

    function formatTime(time: string | number | Date, spe = ''): string {
        const year = String(new Date(time).getFullYear());
        const month = addZero(String(new Date(time).getMonth() + 1));
        const day = addZero(String(new Date(time).getDate()));
        return year + spe + month + spe + day;
    }

    const AUTH_RESULT = requestPermissionsFromUser(permissionList);
    if (AUTH_RESULT.authResults[0] === -1 || AUTH_RESULT.authResults[1] === -1 || AUTH_RESULT.authResults[2] === -1) {
        //print("Never comes here");
    } else {
        var appLastStartTime : string = "12007377158";
        var appStartTimeStamp = new Date().getTime();
        var isSameDay = false;
        if (appLastStartTime !== 'never') {
            if (formatTime(Number(appLastStartTime), '') === formatTime(appStartTimeStamp, '')) {
                isSameDay = true;
            }
        }
    }

    class SamplePropertyObj {
        private storage_ = new Map();
        constructor(prop : string, val : number) {
            this.storage_.set(prop, val);
        }
        setOrCreate(propName, newValue) {
            if (newValue == undefined) {
                return false;
            }
            var p = this.storage_.get(propName);
            if (p) {
                this.storage_.set(p, newValue);
            }
            return true;
        }
    }

    
    var prop : string = "yao";
    var oldValue : number = 1;
    var sample = new SamplePropertyObj(prop, oldValue);
    var newValue: number = 2;
    sample.setOrCreate(prop, newValue);

    interface IPropertySubscriber {

    }

    class SubscriberManager {
        private subscriberById_ = new Map();
        private static instance_: SubscriberManager = new SubscriberManager();

        public static Get() { return SubscriberManager.instance_; }
        constructor () {
            var obj1 = {
                hasChange : true,
                name : "ob1",
            }
            var obj2 = {
                hasChange : true,
                name : "ob2",
            }
            var obj3 = {
                propertyHasChanged : true,
                name : "ob3",
            }
            var obj4 = {
                propertyHasChanged : true,
                name : "ob4",
            }
            this.subscriberById_.set(1, obj1);
            this.subscriberById_.set(2, obj2);
            this.subscriberById_.set(3, obj3);
            this.subscriberById_.set(4, obj4);
        }
        public get(id): object {
            return this.subscriberById_.get(id);
        }
    }

    function notifyHasChanged (newValue : string) {

        var registry = SubscriberManager.Get();
        var subscribers = new Set();
        subscribers.add(1);
        subscribers.add(2);
        subscribers.add(3);
        subscribers.add(4);

        subscribers.forEach((id) => {
            var subscriber = registry.get(id);
            if (subscriber) {
                if ('hasChanged' in subscriber) {
                    //print("hasChanged" + newValue);
                }
                if ('viewProperyHasChanged' in subscriber) {
                    //print("hasChanged" + newValue);
                } else if ('propertyHasChanged' in subscriber) {
                    //print("hasChanged" + newValue);
                }

            }
        })
    }

    notifyHasChanged("newValue1");
    notifyHasChanged("newValue2");
    notifyHasChanged("newValue3");

    enum DeviceType {
        DEFAULT = 'default',
        PHONE = 'phone',
        TABLET = 'tablet',
        TV = 'tv',
        CAR = 'car',
        SMARTVISON = 'smartVision',
        WEARABLE = 'wearable',
        LITEWEARABLE = 'liteWearable',
    }

    class DeviceInfo {

        private deviceType;

        constructor (type) {
            this.deviceType = type;
        }

        IsPhone() : boolean {
            const phoneTypes = [
                DeviceType.DEFAULT,
                DeviceType.PHONE,
            ];
            return phoneTypes.indexOf(this.deviceType) !== -1;
        }

        IsTablet() : boolean {
            return this.deviceType === DeviceType.TABLET;
        }
    }
    
    var di = new DeviceInfo(DeviceType.PHONE);
    di.IsPhone();

    class MetaData {
        id: number;
        displayName: string;
        cover1To1: string;
        cover9To16: string;
        size: string;
        uri: string;
        dateModified: string;
        duration: string;
        width: string;
        mimeType;
        mediaType;
        title;
        relativePath;
        parent;
        dateAdded;
        dateTaken;
        artist;
        audioAlbum;
        height;
        orientation;
        albumId;
        albumUri;
        albumName;
        isSoftDeleted;

        constructor(displayName: string, size: string,  isSoftDeleted : number, uri?: string) {
            this.displayName = displayName;
            this.size = size;
            this.isSoftDeleted = isSoftDeleted;
            this.uri = uri;
        }
    }

    enum SoftDeletedType {
        IS_SOFT_DELETED = 1,
        IS_NOT_SOFT_DELETED = 0,
    }
    
    var metaList : MetaData[] = [new MetaData("d1", "1", 0), new MetaData("d2", "2", 1), new MetaData("d3", "3", 1)]

    function getVideoCount(list: MetaData[]): number {
        const newList = list.filter((one) => {
            return one.isSoftDeleted !== SoftDeletedType.IS_SOFT_DELETED;
        });
        return newList.length;
    }

    getVideoCount(metaList);

    class SyncedPropertyObjectTwoWay {
        id : number
        link: string
        static addOwningProperty(objDest : any, objSrc : any) : boolean {
            if (objSrc) {
                objDest.id = objSrc.id;
                objDest.link = objSrc.link;
                return true;
            }
            return false;
        }
    }

    var templateObj = {
        id : 1,
        link : "link1",
    };
    var syncObj = new SyncedPropertyObjectTwoWay();
    SyncedPropertyObjectTwoWay.addOwningProperty(syncObj, templateObj);

    class VideoEditMenuItem {
        private listOfListeners = new Set();
        recordDependentUpdate () {
            const elementId = this.listOfListeners.size + 1;
            if (elementId < 0) {
                return;
            }
            this.listOfListeners.add(elementId);
        }
    }
    
    var videoEditMenuItem = new VideoEditMenuItem();
    videoEditMenuItem.recordDependentUpdate();
    videoEditMenuItem.recordDependentUpdate();
    videoEditMenuItem.recordDependentUpdate();
    videoEditMenuItem.recordDependentUpdate();
    videoEditMenuItem.recordDependentUpdate();

    enum ListGap {
        PAD_GAP = 12,
        PHONE_GAP = 8,
    }

    enum ColumnCount {
        ONE_COLUMN = 1,
        TWO_COLUMNS = 2,
        THREE_COLUMNS = 3,
        FOUR_COLUMNS = 4,
    }

    enum ListViewType {
        LIST = 'list',
        GRID = 'grid',
    }

    class VideoGridComponents {
        private isLandscape : boolean = false;
        private gap : number;
        private deviceInfo : DeviceInfo;
        private isPadLandsModel : boolean;
        private columns : number;
        private viewType : string =  "grid";

        constructor (deviceInfo) {
            this.deviceInfo = new DeviceInfo(DeviceType.TABLET);
        }
        
        setGap () {
            this.gap = this.isLandscape && this.deviceInfo.IsTablet() ? ListGap.PAD_GAP : ListGap.PHONE_GAP;
        }

        getColumns (viewType, isLandscape) : number {
            // 记录返回值：当前列数
            let columns: number;
            // 手机
            if (this.deviceInfo.IsPhone()) {
                // 列表 1，网格2
                columns = viewType === ListViewType.LIST ? ColumnCount.ONE_COLUMN : ColumnCount.TWO_COLUMNS;
            } else if (isLandscape) {
                // 非手机，横屏 横屏，列表2，网格4
                columns = viewType === ListViewType.LIST ? ColumnCount.TWO_COLUMNS : ColumnCount.FOUR_COLUMNS;
            } else if (!isLandscape) {
                // 非手机，竖屏 竖屏，列表1，网格3
                columns = viewType === ListViewType.LIST ? ColumnCount.ONE_COLUMN : ColumnCount.THREE_COLUMNS;
            } else {
                // 兜底，列表1， 网格2
                columns = viewType === ListViewType.LIST ? ColumnCount.ONE_COLUMN : ColumnCount.TWO_COLUMNS;
            }
            return columns;
        }

        setColumnsByDeviceType () {
            if (this.isLandscape && !this.deviceInfo.IsPhone()) { // 非手机，横屏
                this.isPadLandsModel = true;
            }
            this.columns = this.getColumns(this.viewType, this.isLandscape);
        }

        onViewTypeChange () {
            this.setGap();
            this.setColumnsByDeviceType();
        }

        onChange(mediaQueryResult) {
            var isLandscape = mediaQueryResult.matches;
            this.onViewTypeChange();
        }
    }


    var di2 = new DeviceInfo(DeviceType.TABLET);
    var grid = new VideoGridComponents(di2);
    var mediaQueryResult = {
        matches : true
    };

    grid.onChange(mediaQueryResult);

    var displayName = "hi,this is a test string";
    displayName.split('').join('\u200B');

    function secondToHHMMSS(second: number | string): string {
        const s = Number(second);
        let t = '';
        if (s > -1) {
            const hour = Math.floor(s / 3600);
            const min = Math.floor(s / 60) % 60;
            const sec = s % 60;
            if (hour > 0) {
                t = `${addZero(hour)}:${addZero(min)}:${addZero(sec.toFixed(0))}`;
            } else {
                t = `${addZero(min)}:${addZero(sec.toFixed(0))}`;
            }
        }
        return t;
    }

    function millisecondToHHMMSS(ms: number | string): string {
        const second = Math.floor(Number(ms) / 1000);
        const hms = secondToHHMMSS(second);
        return hms;
    }

    
    var secondsToProcess = [6547, 4002, 4967, 3032, 4358];
    for (const t in secondsToProcess) {
        millisecondToHHMMSS(t);
    }

    function getThumbnailScale(width: number, height: number): {
        thumbnailWidth: number;
        thumbnailHeight: number;
    } {
        const scale: number = Number(height) / Number(width);
        const MAX_SIZE = 299;
        const thumbnailParams = {
            thumbnailWidth: MAX_SIZE,
            thumbnailHeight: MAX_SIZE * scale,
        };
        return thumbnailParams;
    }

    var c = getThumbnailScale(300, 500).toString();

    class sampleMeta {
        id: number;
        displayName: string;
        cover1To1: string;
        cover9To16: string;
        size: string;
        uri: string;
        duration: string;
        dateModified: string;
        width: string;
        title: string;
        artist: string
        audioAlbum: string;
        height: string;
        isSoftDeleted: number;
        playTime: string;
        constructor (id : number, str : string) {
            this.id = id;
            this.displayName = str;
            this.cover1To1 = str;
            this.cover9To16 = str;
            this.size = str;
            this.uri = str;
            this.duration = str;
            this.dateModified = str;
            this.width = str;
            this.title = str;
            this.artist = str;
            this.audioAlbum = str;
            this.height = str;
            this.isSoftDeleted = id%2 === 0 ? 0 : 1;
            this.playTime = (id*100).toString();
        }
    }

    
    function searchVideos(rawData) {
        const mediaResource: sampleMeta[] = [];
        for (const item of rawData) {
            let thumbnailWidth = 0;
            let thumbnailHeight = 0;
            if (item.width&&item.height) {
                thumbnailWidth = parseInt(getThumbnailScale(item.width, item.height).thumbnailWidth.toString(), 10);
                thumbnailHeight = parseInt(getThumbnailScale(item.width, item.height).thumbnailHeight.toString(), 10);
            }
            const dataItem = {
                id: item.id,
                displayName: item.displayName,
                cover1To1: item.width&&item.height?`${item.uri}/thumbnail/${thumbnailWidth}/${thumbnailHeight}`:'',
                cover9To16: item.width&&item.height?`${item.uri}/thumbnail/${thumbnailWidth}/${thumbnailHeight}`:'',
                size: item.size?.toString() || '',
                uri: item.uri,
                duration: item.duration?.toString() || '',
                dateModified: item.dateModified?.toString() || '',
                width: item.width?.toString() || '',
                title: item.title,
                artist: item.artist,
                audioAlbum: item.audioAlbum,
                height: item.height?.toString() || '',
                isSoftDeleted: 0,
                playTime: '0000',
            };
            mediaResource.push(dataItem);
        }
        return mediaResource;
    }

    var rawData : sampleMeta[] = [];
    for (var i = 0; i < 15; i++) {
        var temp = new sampleMeta(i, i.toString());
        rawData.push(temp);
    }
    var processedData = searchVideos(rawData);
}

function himovie() {
    let start : number = Date.now();
    for (var i = 0; i < 3000; i++) {
        himovieBenchMark();
    }
    let end = Date.now();
    print("himovie_total :", end - start);
    print("execute successfully");
}

himovie();
